Popular Searches
Popular Course Categories
Popular Courses

Weather App with API Integration

Weather App with API Integration

React JS Practical Projects

Weather App with API Integration in React JS

A Weather App with API Integration is a React JS project that fetches real-time weather information from an external weather service and displays details such as temperature, city name, humidity, wind speed, and weather conditions. This project helps developers understand API integration, asynchronous JavaScript, React Hooks, conditional rendering, and error handling.

Course: JustAcademy React JS Training Course

Course Demo: Register for React JS Course Demo


1. Learning Objectives

  • Understand how weather APIs work.
  • Fetch weather data from an external API.
  • Use React useState and useEffect Hooks.
  • Handle asynchronous operations using async/await.
  • Display weather information dynamically.
  • Implement loading states and error messages.
  • Build a responsive weather application using CSS.

2. What Is a Weather App?

A Weather App is a web application that displays weather information for a selected city or location. It obtains weather data from an API and updates the user interface based on the response.

Features

  • Search weather by city name.
  • Display current temperature.
  • Show weather conditions such as sunny, cloudy, or rainy.
  • Display humidity and wind speed.
  • Show loading indicators while fetching data.
  • Display errors for invalid cities or network failures.
  • Provide a responsive layout for desktop and mobile devices.

3. What Is API Integration?

API integration allows a React application to communicate with an external service and retrieve data. A weather service receives a request containing a city or location and returns weather information, usually in JSON format.

Important API Terms

Term Description
API A mechanism that allows applications to communicate.
Endpoint The URL used to request weather data.
API Key A credential used by some providers to authorize requests.
HTTP Request A request sent from the application to the API.
JSON A common format for receiving structured API data.
Response The data returned by the server.
Async/Await JavaScript syntax for working with asynchronous operations.

4. Weather API Providers

A weather API provider supplies current conditions, forecasts, and other meteorological information.

  • OpenWeather API – Provides current weather and forecast services.
  • WeatherAPI – Provides weather conditions and forecast data.
  • Open-Meteo – Provides weather APIs with access options that may not require an API key.

Important: Check the provider's current documentation, API limits, authentication requirements, and usage terms before integrating it into a project.


5. How the Weather App Works

  1. The user enters a city name.
  2. The user clicks the Search button.
  3. React sends a request to the weather API.
  4. The API processes the request and returns a response.
  5. The application converts the response into JSON.
  6. React stores the weather information in state.
  7. The UI displays the temperature, conditions, humidity, and wind speed.
  8. If the request fails, the app displays an appropriate error message.

Application Flow

User Enters City
      |
      v
React Search Form
      |
      v
Fetch Weather API
      |
      v
Check HTTP Response
      |
      v
Convert Response to JSON
      |
      v
Update React State
      |
      v
Display Weather Information
      |
      v
Show Error If Request Fails

6. Technologies Used

Technology Purpose
React JS Builds reusable UI components.
JavaScript Handles application logic and API requests.
HTML/JSX Defines the application's structure.
CSS Styles the weather interface.
Fetch API Sends HTTP requests to the weather service.
useState Stores city, weather, loading, and error data.
useEffect Runs side effects when required by the component.
Vite Provides a development server and build tools.

7. Create a React Project

Install Node.js and npm, then run the following commands in your terminal:

npm create vite@latest weather-app -- --template react
cd weather-app
npm install
npm run dev

Open the local URL shown in the terminal to view the application.

Recommended Project Structure

weather-app/
├── public/
├── src/
│   ├── App.jsx
│   ├── App.css
│   ├── index.css
│   └── main.jsx
├── package.json
└── index.html

8. Configure the Weather API

For this example, use OpenWeather's current weather endpoint. Create an account with the provider and obtain an API key if required. In a Vite project, create a .env.local file in the project root.

VITE_WEATHER_API_KEY=your_api_key_here

Restart the development server after changing environment variables.

Security note: Vite variables prefixed with VITE_ are included in client-side code and are not secret. This approach is suitable for learning with a restricted development key, but production applications should protect private credentials through a backend or serverless function. Never commit real secrets to a public repository.


9. Build the Weather App in App.jsx

The following component lets users search for a city and displays current weather data. It includes loading, error, and empty states.

import { useState } from "react";
import "./App.css";

const API_KEY = import.meta.env.VITE_WEATHER_API_KEY;

function App() {
  const [city, setCity] = useState("");
  const [weather, setWeather] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");

  async function searchWeather(event) {
    event.preventDefault();

    const cityName = city.trim();

    if (!cityName) {
      setError("Please enter a city name.");
      setWeather(null);
      return;
    }

    if (!API_KEY) {
      setError("Weather API key is missing. Check .env.local.");
      setWeather(null);
      return;
    }

    setLoading(true);
    setError("");
    setWeather(null);

    try {
      const url =
        `https://api.openweathermap.org/data/2.5/weather` +
        `?q=${encodeURIComponent(cityName)}` +
        `&appid=${API_KEY}&units=metric`;

      const response = await fetch(url);

      if (!response.ok) {
        if (response.status === 404) {
          throw new Error("City not found. Please check the spelling.");
        }
        if (response.status === 401) {
          throw new Error("API key is invalid or not yet active.");
        }
        throw new Error("Unable to fetch weather. Please try again.");
      }

      const data = await response.json();
      setWeather(data);
    } catch (err) {
      setError(
        err instanceof Error
          ? err.message
          : "Something went wrong."
      );
    } finally {
      setLoading(false);
    }
  }

  return (
    <main className="weather-page">
      <section className="weather-card">
        <h1>Weather App</h1>
        <p className="subtitle">
          Check the current weather of any city
        </p>

        <form onSubmit={searchWeather} className="search-form">
          <input
            type="text"
            value={city}
            onChange={(event) => setCity(event.target.value)}
            placeholder="Enter city name"
            aria-label="City name"
          />
          <button type="submit" disabled={loading}>
            {loading ? "Searching..." : "Search"}
          </button>
        </form>

        {loading && (
          <p role="status" className="message">
            Loading weather information...
          </p>
        )}

        {error && (
          <p role="alert" className="error">
            {error}
          </p>
        )}

        {weather && !loading && (
          <div className="weather-result">
            <h2>
              {weather.name}, {weather.sys.country}
            </h2>
            <p className="temperature">
              {Math.round(weather.main.temp)}°C
            </p>
            <p className="condition">
              {weather.weather[0].description}
            </p>

            <img
              src={`https://openweathermap.org/img/wn/${weather.weather[0].icon}@2x.png`}
              alt={weather.weather[0].description}
            />

            <div className="weather-details">
              <p>
                Humidity:
                <strong> {weather.main.humidity}%</strong>
              </p>
              <p>
                Wind:
                <strong> {weather.wind.speed} m/s</strong>
              </p>
              <p>
                Feels like:
                <strong> {Math.round(weather.main.feels_like)}°C</strong>
              </p>
            </div>
          </div>
        )}
      </section>
    </main>
  );
}

export default App;

Explanation of App.jsx

  • useState stores the input city, weather response, loading status, and error message.
  • event.preventDefault() prevents the form from reloading the page.
  • fetch() sends an HTTP request to the weather API.
  • encodeURIComponent() safely encodes the city name in the URL.
  • response.ok checks whether the HTTP request succeeded.
  • response.json() converts the response body into a JavaScript object.
  • setWeather(data) stores the API response in React state.
  • finally resets the loading state whether the request succeeds or fails.
  • Conditional rendering displays the appropriate result, loading message, or error.

10. Add Styling in App.css

.weather-page {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 24px;
  background: linear-gradient(135deg, #74b9ff, #6c5ce7);
  font-family: Arial, sans-serif;
}

.weather-card {
  width: 100%;
  max-width: 460px;
  padding: 28px;
  border-radius: 20px;
  background: #ffffff;
  box-shadow: 0 12px 35px rgba(0, 0, 0, 0.18);
  text-align: center;
}

.weather-card h1 {
  margin-top: 0;
  color: #2d3436;
}

.subtitle {
  color: #636e72;
}

.search-form {
  display: flex;
  gap: 10px;
  margin: 24px 0;
}

.search-form input {
  min-width: 0;
  flex: 1;
  padding: 12px;
  border: 1px solid #dfe6e9;
  border-radius: 8px;
  font-size: 16px;
}

.search-form button {
  padding: 12px 16px;
  border: none;
  border-radius: 8px;
  background: #0984e3;
  color: white;
  cursor: pointer;
}

.search-form button:disabled {
  cursor: not-allowed;
  opacity: 0.65;
}

.weather-result {
  margin-top: 20px;
}

.temperature {
  margin: 8px 0;
  font-size: 48px;
  font-weight: bold;
  color: #0984e3;
}

.condition {
  text-transform: capitalize;
  color: #636e72;
}

.weather-result img {
  width: 100px;
  height: 100px;
}

.weather-details {
  display: grid;
  grid-template-columns: 1fr;
  gap: 4px;
  padding: 12px;
  border-radius: 12px;
  background: #f1f6fb;
}

.weather-details p {
  margin: 8px 0;
}

.message {
  color: #0984e3;
}

.error {
  color: #c0392b;
  background: #fff0ef;
  padding: 12px;
  border-radius: 8px;
}

@media (max-width: 480px) {
  .weather-card {
    padding: 20px;
  }

  .search-form {
    flex-direction: column;
  }

  .search-form button {
    width: 100%;
  }
}

11. Add Global Styles in index.css

* {
  box-sizing: border-box;
}

body {
  margin: 0;
}

button,
input {
  font: inherit;
}

12. Understanding the Weather API Response

The API returns a JSON object containing current weather details. A simplified example is shown below; the values are illustrative, not live weather data.

{
  "name": "Mumbai",
  "sys": {
    "country": "IN"
  },
  "main": {
    "temp": 29.5,
    "feels_like": 33.1,
    "humidity": 72
  },
  "weather": [
    {
      "description": "scattered clouds",
      "icon": "03d"
    }
  ],
  "wind": {
    "speed": 4.2
  }
}
Property Meaning
data.name City name returned by the API.
data.sys.country Country code.
data.main.temp Temperature in Celsius when units=metric is used.
data.main.feels_like Perceived temperature.
data.main.humidity Relative humidity percentage.
data.weather[0].description Weather condition description.
data.wind.speed Wind speed, in the unit specified by the API.

13. Why Use React useState?

useState stores information that changes while the user interacts with the application. When state updates, React re-renders the relevant UI.

const [city, setCity] = useState("");
const [weather, setWeather] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");

For example, when setWeather(data) runs, React updates the displayed temperature and weather details using the latest response.


14. Why Use useEffect?

useEffect synchronizes a component with external systems and is often used for data fetching. In the example above, the request runs when the user submits the search form, so the API call is placed in the event handler and does not require useEffect.

If you want the app to load weather for a default city automatically when the component mounts, you can use useEffect with appropriate cleanup and error handling. Avoid making duplicate or unnecessary API requests.


15. Error Handling in a Weather App

Problem Possible Solution
City not found Check the city spelling and handle HTTP 404.
Invalid API key Verify credentials and provider activation.
Network failure Show a friendly message and allow retrying.
Empty input Validate the city field before making a request.
API rate limit Respect provider limits and retry according to its guidance.
Missing API key Check environment variable configuration.
Unexpected response Validate required properties before rendering them.

16. Common Mistakes and Their Solutions

  • Forgetting to check response status: Fetch does not automatically reject every HTTP error response. Check response.ok.
  • Forgetting to parse JSON: Use await response.json().
  • Incorrect property names: Check the API documentation and response structure.
  • Not handling loading state: Show a message and disable repeated submissions while a request is running.
  • Exposing secrets: Client-side environment variables are visible to users. Use a backend for private credentials.
  • Incorrect units: Select metric or imperial units and label values correctly.
  • Unsafe rendering: Render API strings as normal React text rather than injecting them as raw HTML.

17. Testing the Weather App

  1. Search for a valid city such as Mumbai or London.
  2. Verify that the city, temperature, humidity, and wind speed appear.
  3. Search for a misspelled city and check the error message.
  4. Submit an empty input and verify validation.
  5. Test with an unavailable network.
  6. Test with a missing or invalid API key.
  7. Check the layout on mobile and desktop screens.
  8. Confirm the loading message appears during the request.

18. Best Practices

  • Keep API request logic organized and reusable.
  • Use async/await and handle rejected requests.
  • Validate user input before sending requests.
  • Use clear loading, success, empty, and error states.
  • Keep API credentials out of public source control.
  • Use accessible labels and meaningful error messages.
  • Do not hardcode live weather values in the UI.
  • Check API documentation, units, rate limits, and licensing.
  • Consider request cancellation or stale-response protection if users can initiate overlapping requests.
  • For larger apps, consider a data-fetching library such as TanStack Query to manage caching, retries, and request state.

19. Project Enhancement Ideas

  • Display a five-day weather forecast.
  • Add Celsius/Fahrenheit conversion.
  • Show sunrise and sunset times.
  • Add a recent-search history.
  • Use weather icons and dynamic background themes.
  • Allow users to search by coordinates.
  • Add location-based weather with explicit user permission.
  • Store favourite cities.
  • Add unit tests for input validation and API error states.

20. Interview Questions and Answers

Q1. What is API integration in React?

API integration allows a React application to request and use data from an external service.

Q2. What is the Fetch API?

The Fetch API is a browser interface for making HTTP requests and reading responses asynchronously.

Q3. Why do we use async/await?

It makes asynchronous code easier to read and allows errors to be handled using try/catch.

Q4. Why is response.ok checked?

It helps identify unsuccessful HTTP responses before trying to use the returned data as a successful result.

Q5. What is JSON?

JSON is a text-based format for exchanging structured data between applications.

Q6. What is useState?

useState is a React Hook used to store and update component state.

Q7. Why display a loading message?

It informs users that the application is waiting for the API response.

Q8. How can an invalid city be handled?

Check the HTTP response and display a clear message when the API returns a not-found status.

Q9. Is a VITE_WEATHER_API_KEY variable secret?

No. Variables exposed to client-side Vite code can be inspected by users. Private keys should be protected on a server.

Q10. Why does React re-render after a state update?

React re-renders components when their state or relevant props change so the interface can reflect updated data.


21. Practical Exercises

  1. Create the React project using Vite.
  2. Connect a weather API and display a city's current temperature.
  3. Add humidity, wind speed, and weather description.
  4. Implement loading and error messages.
  5. Add a Celsius/Fahrenheit switch.
  6. Improve responsive styling for mobile devices.
  7. Write tests for invalid input and API errors.

22. Quick Revision

  • React: Builds the user interface.
  • API: Supplies weather information.
  • Fetch: Sends HTTP requests.
  • JSON: Represents structured response data.
  • useState: Stores dynamic application data.
  • useEffect: Synchronizes with external systems when needed.
  • async/await: Handles asynchronous operations.
  • try/catch/finally: Supports error handling and cleanup of loading state.
  • Conditional rendering: Displays results, errors, and loading indicators as appropriate.

23. Official Documentation and Learning Resources


24. React JS Course and Demo Links

Learn more about React JS concepts, API integration, components, Hooks, and practical projects through the following course resources:

Conclusion

Building a Weather App with API Integration is a practical way to learn how React communicates with external services. By combining React state, the Fetch API, asynchronous JavaScript, conditional rendering, CSS, and error handling, developers can create a useful and responsive application that displays real weather information.

whatsapp